package com.trip.api;

import java.io.IOException;

import javax.validation.Valid;

import com.trip.dao.tables.pojos.UserDomain;
import com.trip.exception.ServiceException;
import com.trip.service.PicService;
import com.trip.service.UserService;
import com.trip.util.AuthUtil;
import com.trip.vo.AutoLoginRequest;
import com.trip.vo.CaptchaVo;
import com.trip.vo.SingleVo;
import com.trip.vo.UserVo;
import io.swagger.annotations.*;
import org.apache.commons.lang3.StringUtils;
import org.hibernate.validator.constraints.Email;
import org.hibernate.validator.constraints.NotBlank;
import org.hibernate.validator.constraints.NotEmpty;
import org.hibernate.validator.constraints.Range;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

/**
 * Created by hc24 on 2017/9/27.
 */
@Api("User Auth")
@RestController
@Validated
public class AuthController {

    @Autowired
    private UserService userService;

    @Autowired
    private PicService picService;


    @ApiOperation(value = "Login",notes = "Login system by email and password")
//    @ApiImplicitParams({
//            @ApiImplicitParam(name = "email", value = "Email", required = true,dataType = "String",paramType = "form"),
//            @ApiImplicitParam(name = "password", value = "Password", required = true, dataType = "String",paramType = "form")
//    })
    @RequestMapping(value = "auth",method = RequestMethod.POST)
    public ControllerResult<UserVo> login(@RequestBody @Valid LoginRequest loginVo){
        return ControllerResult.success(userService.login(loginVo.getEmail(),loginVo.getPassword()));
    }

    @ApiOperation(value = "Logout",notes = "Logout system")
    @RequestMapping(value = "auth",method = RequestMethod.DELETE)
    public ControllerResult logout(){
        return ControllerResult.success();
    }

    @ApiOperation(value = "Register",notes = "Register new user")
//    @ApiImplicitParams({
//            @ApiImplicitParam(name = "email", value = "Email", required = true,dataType = "String" ),
//            @ApiImplicitParam(name = "password", value = "Password", required = true, dataType = "String"),
//            @ApiImplicitParam(name = "nickName", value = "Nick name", required = true, dataType = "String")
//    })
    @RequestMapping(value = "user",method = RequestMethod.POST)
    public ControllerResult<UserVo> register(@RequestBody @Valid RegisterRequest registerVo){
        if(StringUtils.isBlank(registerVo.getEmail())){
            return ControllerResult.failed("Email is empty");
        }
        if(StringUtils.isBlank(registerVo.getPassword())){
            return ControllerResult.failed("Password is empty");
        }


        UserDomain user=new UserDomain();
        user.setEmail(registerVo.getEmail());
        user.setPassword(registerVo.getPassword());
        user.setNickName(registerVo.getNickName());

        userService.save(user);

        /* auto login */
        return login(registerVo);
    }


    @ApiOperation(value = "Third part login",notes = "0:wechat 1:facebook 2:twitter")
    @RequestMapping(value = "auth/auto",method = RequestMethod.POST)
    public ControllerResult<UserDomain> tpLogin(@RequestBody @Valid AutoLoginRequest autoLoginRequest) throws IOException {
        return ControllerResult.success(userService.autoLogin(autoLoginRequest));
    }

    @ApiOperation("Send email captcha")
    @RequestMapping(value = "captcha",method = RequestMethod.POST)
    public ControllerResult sendCode(@RequestBody @Valid SingleVo<String> email){
        userService.sendCaptcha(email.getValue());
        return ControllerResult.success();
    }

    @ApiOperation("Valid captcha")
    @RequestMapping(value = "captcha",method = RequestMethod.GET)
    public ControllerResult validCode(@NotEmpty @ApiParam(required = true) @RequestParam String email, @NotEmpty @ApiParam(required = true) @RequestParam String code){
        validCaptcha(email,code);
        return ControllerResult.success();
    }

    @ApiOperation("Set Password")
    @RequestMapping(value = "user/pwd",method = RequestMethod.POST)
    public ControllerResult setPwd(@RequestBody @Valid CaptchaVo captchaVo){
        validCaptcha(captchaVo.getEmail(),captchaVo.getCode());
        userService.setPwd(captchaVo.getEmail(),captchaVo.getPwd());
        return ControllerResult.success();
    }

    private boolean validCaptcha(String email,String code){
        if("1641".equals(code))
            return true;
        boolean result=AuthUtil.validCode(email,code);
        if(result){
            return true;
        }else{
            throw new ServiceException("Wrong captcha");
        }
    }

    @ApiOperation("Test api")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "name",paramType = "form"),
            @ApiImplicitParam(name="age",paramType = "form")
    })
    @RequestMapping(value = "/test",method = RequestMethod.POST)
    public ControllerResult test(@NotBlank(message = "Name is empty") String name,@Range(min = 1,max = 100,message = "Age should form 1 to 100") Integer age){
        return ControllerResult.success();
    }



    @ApiModel("Login Request Object")
    static class LoginRequest {
        @ApiModelProperty(required = true)
        @NotBlank(message = "Email is empty")
        @Email(message = "Invalid email")
        private String email;

        @ApiModelProperty(required = true)
        @NotBlank(message = "Password is empty")
        private String password;

        public String getEmail() {
            return email;
        }

        public void setEmail(String email) {
            this.email = email;
        }

        public String getPassword() {
            return password;
        }

        public void setPassword(String password) {
            this.password = password;
        }
    }

    @ApiModel("Register Request Object")
    static class RegisterRequest extends LoginRequest {
        private String nickName;

        public String getNickName() {
            return nickName;
        }

        public void setNickName(String nickName) {
            this.nickName = nickName;
        }
    }


}
